package cn.levi.sensitive.component;

import cn.hutool.dfa.WordTree;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/**
 * 敏感词处理器，内存缓存。当敏感词变化时要重新加载
 * @author lei
 * @since 2025/2/18
 */
@Component
@RequiredArgsConstructor
public class SensitiveHandler {

	/**
	 * 敏感词缓存前缀
	 */
	private static final String SENSITIVE_WORD_CACHE_PREFIX = "simple-tool:sensitive_word_cache";

	private final RedisTemplate<String, Object> redisTemplate;
	private final SensitiveFactory sensitiveFactory;


	/**
	 * 用来判断是否存在敏感词
	 *
	 * @param content 内容
	 * @return
	 */
	public boolean isSensitive(String content) {
		WordTree wordTree = getWordTree();
		return wordTree.isMatch(content);
	}

	/**
	 * 获取单词树
	 *
	 * @return
	 */
	private WordTree getWordTree() {
		Set<Object> wordTree = redisTemplate.opsForSet().members(SENSITIVE_WORD_CACHE_PREFIX);
		WordTree tree = new WordTree();
		if(wordTree==null||wordTree.isEmpty()){
			//获取数据库的敏感词
			Set<String> sensitiveWords = sensitiveFactory.getSensitiveWords();
			//保存
			String[] sensitiveWordsArray = sensitiveWords.toArray(new String[0]);
			if (sensitiveWordsArray.length > 0){
				redisTemplate.opsForSet().add(SENSITIVE_WORD_CACHE_PREFIX, sensitiveWordsArray);
				tree.addWords(sensitiveWordsArray);
			}
			return tree;
		}
		for (Object item : wordTree) {
			tree.addWord(item.toString());
		}
		return tree;
	}

	/**
	 * 返回所有的敏感关键字
	 *
	 * @param content 内容
	 * @return
	 */
	public List<String> matchAllSensitive(String content) {
		WordTree wordTree = getWordTree();
		return wordTree.matchAll(content);
	}


	/**
	 * 刷新敏感词库
	 *
	 * @return
	 */
	public void refreshSensitiveWord() {
		redisTemplate.delete(SENSITIVE_WORD_CACHE_PREFIX);
		Set<String> sensitiveWords = sensitiveFactory.getSensitiveWords();
		//保存
		String[] sensitiveWordsArray = sensitiveWords.toArray(new String[0]);
		if (sensitiveWordsArray.length > 0){
			redisTemplate.opsForSet().add(SENSITIVE_WORD_CACHE_PREFIX, sensitiveWordsArray);
		}
	}
	/**
	 * 删除敏感词
	 *
	 * @return
	 */
	public void removeSensitiveWord(String word) {
		if (isSensitive(word)) {
			refreshSensitiveWord();
		}
	}

	/**
	 * 添加敏感词
	 *
	 * @param word 单词
	 * @return
	 */
	public void addSensitiveWord(String word) {
		WordTree wordTree = getWordTree();
		if (wordTree.isMatch(word)) {
			return;
		}
		wordTree.addWord(word);
		redisTemplate.opsForSet().add(SENSITIVE_WORD_CACHE_PREFIX, word);
	}
}
